using System.Collections.Generic;
using UnityEngine;
using System.Data;
using System.IO;
using System;
using Unity.Plastic.Newtonsoft.Json.Linq;
public class ExcelEditor
{

    /// <summary>
    /// 表格的存放位置
    /// </summary>
    static string configPath = "File/策划配置/config";

    /// <summary>
    /// 模板存放位置
    /// </summary>
    static string scriptsPath = "/Scripts/HotFix/Config/Model/";

    /// <summary>
    /// json文件存放位置
    /// </summary>
    static string jsonPath = "/GameRes/Config/Json/";

    /// <summary>
    /// 表格数据列表
    /// </summary>
    static List<TableData> dataList = new List<TableData>();



    /// <summary>
    /// 遍历文件夹，读取所有表格
    /// </summary>
    [UnityEditor.MenuItem("Tools/ReadExcel")]
    public static void ReadExcel()
    {
        Debug.LogError(Application.dataPath);
        if (Directory.Exists(configPath))
        {
            //获取指定目录下所有的文件
          
            DirectoryInfo direction = new DirectoryInfo(Application.dataPath.Replace("Assets", "") + configPath);
            FileInfo[] files = direction.GetFiles("*", SearchOption.AllDirectories);
            Debug.Log("fileCount:" + files.Length);

            for (int i = 0; i < files.Length; i++)
            {
                if (files[i].Name.EndsWith(".meta") || !files[i].Name.EndsWith(".xlsx"))
                {
                    continue;
                }
                Debug.Log("FullName:" + files[i].FullName);
            }
            UnityEditor.AssetDatabase.Refresh();
        }
        else
        {
            Debug.LogError("ReadExcel configPath not Exists!");
        }
    }

    /// <summary>
    /// 生成json文件
    /// </summary>
    static void CreateJson(DataSet result, DataTable table, string fileName)
    {
        // 获取表格有多少列 
        int columns = table.Columns.Count;
        // 获取表格有多少行 
        int rows = table.Rows.Count;

        TableData tempData;
        string value;
        JArray array = new JArray();

        //第一行为表头，第二行为类型 ，第三行为字段名 不读取
        for (int i = 3; i < rows; i++)
        {
            for (int j = 0; j < columns; j++)
            {
                // 获取表格中指定行指定列的数据 
                value = table.Rows[i][j].ToString();

                if (string.IsNullOrEmpty(value))
                {
                    continue;
                }
                tempData = new TableData();
                tempData.type = table.Rows[1][j].ToString();
 
                tempData.fieldName = table.Rows[0][j].ToString();

               
                tempData.value = value;
                //Debug.LogError("type:" + tempData.type + " fieldName:" + tempData.fieldName + " value:" + tempData.value);
                dataList.Add(tempData);
            }

            if (dataList != null && dataList.Count > 0)
            {
                Unity.Plastic.Newtonsoft.Json.Linq.JObject tempo = new Unity.Plastic.Newtonsoft.Json.Linq.JObject();
                foreach (var item in dataList)
                {
                    switch (item.type.ToLower())
                    {
                        case "string":
                            tempo[item.fieldName] = GetValue<string>(item.value);
                            break;
                        case "int":
                            tempo[item.fieldName] = GetValue<int>(item.value);
                            break;
                        case "float":
                            tempo[item.fieldName] = GetValue<float>(item.value);
                            break;
                        case "bool":
                            tempo[item.fieldName] = GetValue<bool>(item.value);
                            break;
                        case "string[]":
                            tempo[item.fieldName] = new Unity.Plastic.Newtonsoft.Json.Linq.JArray(GetList<string>(item.value, ','));
                            break;
                        case "int[]":
                            tempo[item.fieldName] = new JArray(GetList<int>(item.value, ','));
                            break;
                        case "float[]":
                            tempo[item.fieldName] = new JArray(GetList<float>(item.value, ','));
                            break;
                        case "bool[]":
                            tempo[item.fieldName] = new JArray(GetList<bool>(item.value, ','));
                            break;
                        case "arr":
                            tempo[item.fieldName] = new JArray(GetList<int>(item.value, ','));
                            break;
                        case "arrs":

                            if (item.value != null && item.value.Length > 0)
                            {
                                string str = item.value.Trim();
                                str = str.Remove(0, 1);
                                str = str.Remove(str.Length - 1, 1);
                                List<JArray> arrs = new List<JArray>();
                                string[] ss = str.Split("],");
                                for (int j = 0; j < ss.Length-1; j++)
                                {
                                    ss[j] += "]";
                                }
                                for (int j = 0; j < ss.Length; j++)
                                {
                                    arrs.Add(new JArray(GetList<int>(ss[j], ',')));
                                }

                                tempo[item.fieldName] = new JArray(arrs);
                            }
                            //tempo[item.fieldName] = item.value;
                            break;
                    }
                }

                if (tempo != null)
                    array.Add(tempo);
                dataList.Clear();
            }
        }

        //JObject o = new JObject();
        //o["datas"] = array;
        //o["version"] = "20200331";
        //File.WriteAllText(UnityEngine.Application.dataPath + jsonPath + fileName + ".json", o.ToString());
        File.WriteAllText(UnityEngine.Application.dataPath + jsonPath + fileName + ".json", array.ToString());
    }

    static List<T> GetList1<T>(string str, char spliteChar)
    {
        int index = 0;
        while (index < str.Length)
        {
            if(str[index].Equals("["))
            {
                index++;
            }
            else
            {
                break;
            }
        }
        return null;
    }

    /// <summary>
    /// 字符串拆分列表
    /// </summary>
    static List<T> GetList<T>(string str, char spliteChar)
    {
        str = str.Remove(0,1);
        str = str.Remove(str.Length-1, 1);
        string[] ss = str.Split(spliteChar);
        int length = ss.Length;
        List<T> arry = new List<T>(ss.Length);
        for (int i = 0; i < length; i++)
        {
            if (ss[i] == "")
                break;
            arry.Add(GetValue<T>(ss[i]));
        }
        return arry;
    }

    static T GetValue<T>(object value)
    {
        return (T)Convert.ChangeType(value, typeof(T));
    }

    /// <summary>
    /// 生成实体类模板
    /// </summary>
    static void CreateTemplate(DataSet result,DataTable table,string fileName)
    {
        if (!Directory.Exists(UnityEngine.Application.dataPath + scriptsPath))
        {
            Directory.CreateDirectory(UnityEngine.Application.dataPath + scriptsPath);
        }

        field = "";
        string arr = "arr";// int-arr,string-arr 或者 object-arr
        string id = null;
        for (int i = 0; i < table.Columns.Count; i++)
        {
            string typeStr = table.Rows[1][i].ToString();
            typeStr = typeStr.ToLower();
            
            
            if (typeStr.Contains(arr))
            {
                string type = "int";
                switch (typeStr)
                {
                    case "int-arr":
                        type = "int";
                        break;
                    case "string-arr":
                        type = "string";
                        break;
                    case "float-arr":
                        type = "float";
                        break;
                }
                int count = typeStr.Substring(arr.Length-1, typeStr.Length-arr.Length).Length+1;
                //typeStr = typeStr.Replace(arr, "");
                typeStr = type;
                for (int j = 0; j < count; j++)
                {
                    typeStr = string.Format("List<{0}>", typeStr);
                }
            }

            string nameStr = table.Rows[0][i].ToString();
            if (string.IsNullOrEmpty(typeStr) || string.IsNullOrEmpty(nameStr)) continue;

            if (nameStr.ToLower().Equals("id"))
            {
                id = nameStr;
            }

            field += "public " + typeStr + " " + nameStr + " { get; set; }\r\t";
        }
      
        string tempStr = Eg_str(id);
        tempStr = tempStr.Replace("@Name", fileName);
        tempStr = tempStr.Replace("@File1", field);
        if (id!=null)
        {
            tempStr = tempStr.Replace("@Id", id);
        }
        File.WriteAllText(UnityEngine.Application.dataPath + scriptsPath + fileName + ".cs", tempStr);

    }

    /// <summary>
    /// 字段
    /// </summary>
    static string field;

    /// <summary>
    /// 实体类模板
    /// </summary>
    static string Eg_str(string id)
    {
       
        string model =
        "using System.Collections.Generic;\r" +
        "using UnityEngine;\r" +
        "using System.Threading.Tasks;\r"+
        "using LitJson;\r\r" +
    
        "public class @Name  {\r\r\t" +
        "@File1 \r\t" +
        "public static string configName = \"@Name\";\r\t" +
        "public static List<@Name> list { get; set; }\r\r\t";
        if (id!=null)
        {
            model += "public static @Name Get(int id)\r\t{\r\t\tforeach (var item in list)\r\t\t\t{\r\t\t\t\tif (item.@Id == id)\r\t\t\t\t{ \r\t\t\t\t\treturn item;\r\t\t\t\t}\r\t\t\t}\r\t\t\treturn null;\r\t\t}\r\t\t";
        }
        model += "public static void Init()\r\t{\r\t\tConfigManager.Instance.Readjson(configName, (json) => {\r\t\t\tif (!string.IsNullOrEmpty( json))\r\t\t\t{\r\t\t\t\t list = JsonMapper.ToObject<List<@Name>>(json);\r\t\t\t\t}\r\t\t}, false);\r\t }\r\r\t\t";

        model += "\r}";

        return model;
    }
}

public struct TableData
{
    public string fieldName;
    public string type;
    public string value;

    public override string ToString()
    {
        return string.Format("fieldName:{0} type:{1} value:{2}", fieldName, type, value);
    }
}